#pragma once
#include <source_location>
#include <exception>
#include <iostream>
#include <string>

#include <cstring>
#include <cerrno>

// LOC需要就地展开以获取信息，所以采用宏
#define LOC std::source_location::current()

namespace my_log
{
    // 日志异常类
    class log_error : public std::exception
    {
    public:
        log_error()
            : std::exception()
            , _error_message(strerror(errno))
        {}

        log_error(const char* msg)
            : std::exception()
            , _error_message(msg)
        {}

        log_error(int err_num)
            : std::exception()
            , _error_message(strerror(err_num))
        {}

        log_error(const std::string& msg)
            : std::exception()
            , _error_message(nullptr)
        {
            _msg_buffer = msg;
            _error_message = _msg_buffer.c_str();
        }

        log_error(std::string&& msg)
            : std::exception()
            , _error_message(nullptr)
        {
            _msg_buffer = std::move(msg);
            _error_message = _msg_buffer.c_str();
        }

        // 重载标准异常类what
        virtual inline const char* what() const noexcept override
        {
            return _error_message;
        }
    private:
        // 错误信息指针
        const char* _error_message;
        // 错误信息存储
        std::string _msg_buffer;
    };
}